03. MiniFlow 架构
MiniFlow 架构
我们看看如何用
MiniFlow
实现这一图表结构。我们将使用一个 Python 类来表示普通节点。
class Node(object):
def __init__(self):
# Properties will go here!
我们知道,每个节点可能会从其他多个节点那接收输入。我们还知道,每个节点都会创建一个输出,这些输出有可能会传递给其他节点。我们添加以下两个列表:一个用于存储对传入节点的引用,另一个用于存储对传出节点的引用。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
每个节点将最终计算出一个表示输出的值。我们将
value
初始化为
None
,表示该值存在,但是尚未设定。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
# A calculated value
self.value = None
每个节点都必须能够将值向前传递,并进行反向传播(稍后会详细介绍)。暂时,我们为前向传播添加一个占位符方法。我们将稍后处理反向传播。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
# A calculated value
self.value = None
def forward(self):
"""
Forward propagation.
Compute the output value based on `inbound_nodes` and
store the result in self.value.
"""
raise NotImplemented
可以进行计算的节点
虽然
Node
定义了每个节点都具有的基本属性,但是只有
Node
的特殊
子类
会出现在图表中。在本次实验练习中,你将构建可以进行计算和存储值的
Node
子类。例如,考虑
Node
的
Input
子类。
class Input(Node):
def __init__(self):
# An Input node has no inbound nodes,
# so no need to pass anything to the Node instantiator.
Node.__init__(self)
# NOTE: Input node is the only node where the value
# may be passed as an argument to forward().
#
# All other node implementations should get the value
# of the previous node from self.inbound_nodes
#
# Example:
# val0 = self.inbound_nodes[0].value
def forward(self, value=None):
# Overwrite the value if one is passed in.
if value is not None:
self.value = value
与
Node
的其他子类不同,
Input
子类实际上并不计算任何内容。
Input
子类仅仅存储了一个
value
,例如数据特征或模型参数(权重/偏置)。
你可以明确地设置
value
,或者用
forward()
方法进行设置。该值然后会传递给神经网络的其他节点。
Add 子类
Add
是
Node
的另一个子类,实际上可以进行计算(加法)。
class Add(Node):
def __init__(self, x, y):
Node.__init__(self, [x, y])
def forward(self):
"""
You'll be writing code here in the next quiz!
"""
注意
__init__
方法
Add.__init__(self, [x, y])
的不同之处。
Input
类没有传入节点,而
Add
类具有 2 个传入节点
x
和
y
,并将这两个节点的值相加。